import {
  ENTITY_TYPES,
  InputValueType,
  KeyEntityType,
  KeyMeshingDim,
  ModelEventType,
  ModelPickSwitchEvent,
  ModelPickTypesEvent,
} from '@app-nextmesh/types';
import { isArray, isPlainObject } from 'lodash';
import React from 'react';
import { events } from '../../utils';
import { ErrorTips } from './components';
import JSONFormField2 from './components/JSONFormField2';
import { isEntityTypes } from './components/utils';

/**
 * 设置支持的拾取模式列表，设置当前拾取模式
 */
export const setPickMode = (initFormFormat: any, newForm: any) => {
  // 更新switchedOnEntityGroup，默认焦点在第一个
  const names = Object.keys(initFormFormat);
  let firstEntityGroup: string = null;
  let pickTypes: string[] = [];
  let mix = false; // 是否混合选择
  for (const name of names) {
    const item = initFormFormat[name];
    const type = item.Type; // 每项首先有一个Type字段
    if (isEntityTypes(type)) {
      mix = item.Mix;
      // 设置支持的拾取模式列表
      pickTypes = isArray(type) ? type : [type];
      // 设置默认焦点
      firstEntityGroup = name;
      break;
    }
  }
  events.emit(ModelEventType.PickTypes, {
    types: pickTypes,
    mix,
  } as ModelPickTypesEvent);

  let currentPickType: string = null;
  for (const name of Object.keys(newForm)) {
    if (name === KeyMeshingDim) {
      currentPickType = ENTITY_TYPES[newForm[name]];
    } else if (name === KeyEntityType) {
      currentPickType = newForm[name];
    }
  }
  if (!mix) {
    // 设置当前拾取模式
    if (!currentPickType) {
      currentPickType = pickTypes[0];
    }
    events.emit(ModelEventType.SetCurrentPickType, {
      type: currentPickType,
      clear: true,
    } as ModelPickSwitchEvent);
  }
  return firstEntityGroup;
};

/**
 * 根据给定的items和typeName生成已有的entity索引映射。
 *
 * @param {string} formType - 表单类型
 * @param {any} formFormat - 表单格式
 * @param {any[]} items - 项目数组。
 * @param {string} typeName - 类型名称，根据typeName字段的值，判断是normal还是pair。
 * @return {Set<string>} id数组
 */
export const getAssignedIndices2 = (
  formType: string,
  formFormat: any,
  items: any[],
  typeName: string,
): Set<string> => {
  const indices = new Set<string>();
  if (!formType || !items || items.length === 0) {
    return indices;
  }

  for (const item of items) {
    const itemType: string = item[typeName];
    if (!itemType) {
      continue;
    }
    const names = Object.keys(item);
    names.forEach((name) => {
      const field = item[name];
      const type = formFormat[name]?.Type;

      if (!type) {
        return;
      }
      // 判断是否是entity类型
      if (isEntityTypes(type)) {
        if (
          (itemType.endsWith('Pair') && formType.endsWith('Pair')) ||
          (!itemType.endsWith('Pair') && !formType.endsWith('Pair'))
        ) {
          if (field?.length > 0) {
            field.forEach((value) => {
              indices.add(value);
            });
          }
        }
      }
    });
  }
  return indices;
};
interface IProps {
  readonly: boolean;
  formData: any;
  formFormat: any;
  handleInputChange: (name: string, value: InputValueType) => void;
  indicesAssigned?: Set<string>;
  switchedOnEntityGroup?: string;
  handleSwitchEntityGroup?: (name: string) => void;
}
/**
 * 根据 formFormat 生成对应的表单界面
 */
const JSONFormatForm2 = React.memo(function JSONFormatForm2({
  readonly,
  formData,
  formFormat,
  handleInputChange,
  indicesAssigned,
  switchedOnEntityGroup,
  handleSwitchEntityGroup,
}: IProps) {
  /**
      formFormat 格式示例：
      {
        "Selection": {
          "Type": "Volume" // 或者数组 ["Vertex", "Edge"]
        },
        "Force": {
          "Type": "Arrayd",
          "Unit": "N",
          "Default": [0.0, 0.0, 0.0]
        }
      }
     */
  if (!isPlainObject(formFormat)) {
    return <ErrorTips>格式错误，必须是一个JSON对象</ErrorTips>;
  }
  const names = Object.keys(formFormat);
  // 如果names只有一个Label，则直接返回空
  if (names.length === 1 && names[0] === 'Label') {
    return <></>;
  }
  const children = names.flatMap((name) => {
    const format = formFormat[name];
    const data = formData[name];
    return (
      <JSONFormField2
        key={name}
        readonly={readonly}
        initName={name}
        formFormat={format}
        formData={data}
        onChange={handleInputChange}
        indicesAssigned={indicesAssigned}
        switchedOnEntityGroup={switchedOnEntityGroup}
        onSwitchEntityGroup={handleSwitchEntityGroup}
      />
    );
  });
  return <>{children}</>;
});
export default JSONFormatForm2;
